package com.sfzd5;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.stream.JsonWriter;
import com.sfzd5.git.FileRepositoryManager;
import com.sfzd5.git.Repository;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.http.server.GitServlet;

import java.io.*;
import java.util.ArrayList;

/**
 * Server to handle access to git repositories over HTTP.
 * This server uses Jetty as the embedded servlet container
 * running the servlet GitServlet from the JGit project.
 */
public class JGitHttpServer {

    private final static String TAG = JGitHttpServer.class.getSimpleName();


    //default parameter values
    Config config;
    private Server server;
    private RepositoryList repositoryList;

    public int getHttpServerPort() {
        return config.HttpServerPort;
    }
    public String getGitLocalPath() {
        return config.GitLocalPath;
    }
    public RepositoryList getRepositoryList() {
        return repositoryList;
    }

    public JGitHttpServer () throws IOException {

        config = loadConfig();

        File basePathFile = new File(config.GitLocalPath);
        if(!basePathFile.exists()) basePathFile.mkdirs();

        repositoryList = loadRepositoryListJson();

        //set up the JGit's GitServlet
        ServletHandler servletHandler = new ServletHandler();
        ServletHolder servletHolder = servletHandler.addServletWithMapping(GitServlet.class, "/*");

        servletHolder.setInitParameter("base-path", config.GitLocalPath); //path to the git repositories
        servletHolder.setInitParameter("export-all", "true"); //yes, true, 1, on: export all repositories
        //no, false, 0, off: export no repositories


        //start up the http server
        server = new Server(config.HttpServerPort);
        server.setHandler(servletHandler);
    }

    public void start() throws Exception{
        server.start();
    }

    public void stop() throws Exception {
        server.stop();
    }

    public String printServerInfo() {
        StringBuilder sb = new StringBuilder();
        sb.append("这是利用jGit包制作的一个Git http服务器。").append("\n")
                .append("可做为一个U盘随身Git服务器使用。").append("\n")
                .append("Git http服务端口：" + config.HttpServerPort +", 存储路径：" + config.GitLocalPath).append("\n")
                .append("服务端口和存储路径可在config.json文件中修改").append("\n")
                .append("使用方法：").append("\n")
                .append("1. 打开软件，创建仓库后点开始启动Git http服务。").append("\n")
                .append("2. 仓库地址：http://127.0.0.1:" + config.HttpServerPort + "/ + 仓库的映射名称").append("\n")
                .append("无需密码验证，可以直接下拉或提交。");
        return sb.toString();
    }

    Config loadConfig() throws IOException {
        Config config = null;
        File jsonFile = new File("config.json");
        if(jsonFile.exists()){
            FileReader reader = new FileReader(jsonFile);
            config = new Gson().fromJson(reader, Config.class);
            reader.close();
        } else {
            config = new Config();
            FileWriter stream = new FileWriter(jsonFile);
            new Gson().toJson(config, Config.class, new JsonWriter(stream));
            stream.close();
        }
        return config;
    }

    RepositoryList loadRepositoryListJson() throws IOException {
        RepositoryList repositoryList = null;
        File jsonFile = new File(config.GitLocalPath, "rec.json");
        if(jsonFile.exists()){
            FileReader reader = new FileReader(jsonFile);
            repositoryList = new Gson().fromJson(reader, RepositoryList.class);
            reader.close();
        } else {
            repositoryList = new RepositoryList();
            repositoryList.repositories = new ArrayList<>();
        }
        return repositoryList;
    }

    public void saveRepositoryListJson() throws IOException {
        File jsonFile = new File(config.GitLocalPath, "rec.json");
        FileWriter stream = new FileWriter(jsonFile);
        new Gson().toJson(repositoryList, RepositoryList.class, new JsonWriter(stream));
        stream.close();
    }


    public org.eclipse.jgit.lib.Repository openRepository(final String mapping) throws RepositoryNotFoundException {
        return new FileRepositoryManager(config.GitLocalPath).openRepository(mapping).getRepository();
    }

    public void renameRepository(final String mapping, final String newMapping) {
        try {
            new FileRepositoryManager(config.GitLocalPath).renameRepository(mapping, newMapping);
        } catch (RepositoryNotFoundException e) {
            // TODO: Put some dialog message here.
        }
    }

    public org.eclipse.jgit.lib.Repository createRepository(Repository rep) throws IOException {
        if(repositoryList.contains(rep)){
            return null;
        } else {
            repositoryList.repositories.add(rep);
            saveRepositoryListJson();
            return new FileRepositoryManager(config.GitLocalPath).createRepository(rep.getMapping()).getRepository();
        }
    }

    public void deleteRepository(final Repository rep) throws IOException {
        repositoryList.repositories.remove(rep);
        saveRepositoryListJson();
        new Thread() {
            @Override
            public void run() {
                try {
                    new FileRepositoryManager(config.GitLocalPath).deleteRepository(rep.getMapping());
                } catch (RepositoryNotFoundException e) {
                }
            }
        }.start();
    }

}